#include "hqcustomplot.h"
#include <QtMath>

QCPItemMaker::QCPItemMaker(QCustomPlot *parentPlot,QString text) :
  QCPItemTracer(parentPlot)
{
    setInterpolating(true);
//    setPen(QPen(Qt::black));
//    setBrush(Qt::yellow);
    setSize(30);
    this->text=text;
}

QCPItemMaker::~QCPItemMaker()
{
}

void QCPItemMaker::SetDeltaEn(bool en)
{
    this->isDelta = en;
}

void QCPItemMaker::SetDeltaRef(int ref)
{
    this->m_refMkr = ref;
}

void QCPItemMaker::setGraph(QCPGraph *graph)
{
    this->setPen(graph->pen());
    QCPItemTracer::setGraph(graph);
}

/* inherits documentation from base class */
double QCPItemMaker::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const
{
    Q_UNUSED(details)
    if (onlySelectable && !mSelectable)
        return -1;

    QPointF center(position->pixelPoint());
    double w = mSize/2.0;
    QRect clip = clipRect();
    if (clip.intersects(QRectF(center-QPointF(0.5*w, 2*w), center+QPointF(0.5*w, 2*w)).toRect()))
    {
        QRectF rect = QRectF(center-QPointF(0.5*w, 2*w), center+QPointF(0.5*w, 2*w));
        bool filledRect = mBrush.style() != Qt::NoBrush && mBrush.color().alpha() != 0;
        return rectSelectTest(rect, pos, filledRect);
    }
    return -1;
}

/* inherits documentation from base class */
void QCPItemMaker::draw(QCPPainter *painter)
{
    updatePosition();
    if (mStyle == tsNone)
        return;

    painter->setPen(mainPen());
    painter->setBrush(mainPen().color());
    painter->setFont(QFont(this->parentPlot()->font().family(), 8));
    QPointF center(position->pixelPoint());
    double w = mSize/2.0;
    QRect clip = clipRect();
    if (clip.intersects(QRectF(center-QPointF(w, w), center+QPointF(w, w)).toRect()))
    {
        QPolygonF polygon;
        if(this->isDelta)
        {
            polygon << center;
            polygon << center+QPointF( 0.5*w, 1.0*w);
            polygon << center+QPointF(-0.5*w, 1.0*w);
            painter->drawPolygon(polygon);
            painter->drawText(QRectF(polygon[2], center+QPointF(0.5*w, 2.0*w) ), Qt::TextDontClip|Qt::AlignHCenter|Qt::AlignVCenter, this->text);//
        }
        else
        {
            polygon << center;
            polygon << center+QPointF( 0.5*w, -1.0*w);
            polygon << center+QPointF(-0.5*w, -1.0*w);
            painter->drawPolygon(polygon);
            painter->drawText(QRectF(center+QPointF(-0.5*w, -2.0*w), polygon[1]), Qt::TextDontClip|Qt::AlignHCenter|Qt::AlignVCenter, this->text);//
        }
    }
}

/*
 * QCustomer类的一个继承类，主要为了增加marker功能
*/
HQCustomPlot::HQCustomPlot(QWidget *parent):
    QCustomPlot(parent)
{
    int i;
    for(i=0;i<10;i++)
    {
        this->mMarkers[i] = new QCPItemMaker(this, QString("%1").arg(i+1));
        mMarkers[i]->setVisible(false);
        mMarkers[i]->setSelectable(false);
    }
    this->activeMarkerIdx=-1;

    this->markerText = new QCPItemText(this);
    this->addItem(markerText);
    this->markerText->setSelectable(true);
    this->markerText->setTextAlignment(Qt::AlignLeft);
    this->markerText->setPositionAlignment(Qt::AlignLeft | Qt::AlignTop);
    this->markerText->position->setType(QCPItemPosition::ptAxisRectRatio);
    this->markerText->position->setCoords(0.05, 0.05); // place position at center/top of axis rect
    this->markerText->setPen(QPen(Qt::green));
    this->markerText->setBrush(Qt::green);
    this->markerText->setFont(QFont(font().family(), 12));
    this->markerText->setText(QString("Marker Value:\n"));
    this->markerText->setVisible(this->mMarkerTextEn);
}

HQCustomPlot::~HQCustomPlot()
{
    int i;
    for(i=0;i<10;i++)
    {
        delete this->mMarkers[i];
    }
}

QCPItemMaker *HQCustomPlot::marker(int index) const
{
    if(index>=0 && index<MARKERNUM)
    {
        return mMarkers[index];
    }
    else
    {
        qDebug() << "HQCustomPlot::marker, require marker index exceed!";
        return 0;
    }
}

bool HQCustomPlot::addMarker(int index, int mkrToTrace, bool delta, int ref)
{
    double AxisCenter;
    int ToTrace;
    if(index>=0 && index<MARKERNUM)
    {
        AxisCenter = this->xAxis->range().center();
        mMarkers[index]->setVisible(true || mMarkers[index]->visible());
        mMarkers[index]->setSelectable(true || mMarkers[index]->selectable());
        if(index==0)
        {
            mMarkers[index]->SetDeltaEn(false);
        }
        else
        {
            mMarkers[index]->SetDeltaEn(delta);
            mMarkers[index]->SetDeltaRef(ref);
        }
        if(mkrToTrace <= 0)
            ToTrace = 0;
        else if(mkrToTrace >= this->graphCount())
            ToTrace = this->graphCount()-1;
        else
            ToTrace = mkrToTrace;
        mMarkers[index]->setGraph(this->graph(ToTrace));
        mMarkers[index]->setGraphKey(AxisCenter);
        this->replot();
        return true;
    }
    else
    {
        qDebug() << "HQCustomPlot::addMarker, require marker index exceed!";
        return false;
    }
}

bool HQCustomPlot::removeMarker(int index)
{
    if(index>=0 && index<MARKERNUM)
    {
        mMarkers[index]->setVisible(false && mMarkers[index]->visible());
        mMarkers[index]->setSelectable(false);
        mMarkers[index]->setSelected(false);
        mMarkers[index]->SetDeltaEn(false);
        mMarkers[index]->SetDeltaRef(0);
        this->replot();
        return true;
    }
    else
    {
        qDebug() << "HQCustomPlot::removeMarker, require marker index exceed!";
        return false;
    }
}

int HQCustomPlot::clearMarker()
{
    int i;
    for(i=0;i<MARKERNUM;i++)
    {
        removeMarker(i);
    }
    this->replot();
    return MARKERNUM;
}

void HQCustomPlot::mousePressEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton)
    {
        double minimumDistance = selectionTolerance()*1.1;
        double dist;
        int miniMarkerIdx=-1;
        int n;
        QVariant details;

        dist = this->markerText->selectTest(event->pos(), true, &details);
        if(dist >= 0 && dist < minimumDistance)
        {
            this->markerText->setSelected(true);
            this->activeMarkerIdx= -1;
            QCustomPlot::mousePressEvent(event);
            return;
        }

        for(n=0;n<MARKERNUM;n++)
        {
            if(!(mMarkers[n]->visible() && mMarkers[n]->selectable()))
                continue;
            dist = mMarkers[n]->selectTest(event->pos(), true, &details);
            if(dist >= 0 && dist < minimumDistance)
            {
                minimumDistance= dist;
                miniMarkerIdx=n;
            }
        }
        if (minimumDistance < selectionTolerance())
        {
            mMarkers[miniMarkerIdx]->setSelected(true);
            this->activeMarkerIdx= miniMarkerIdx;
        }
        else
        {
            this->activeMarkerIdx= -1;
        }
    }
    QCustomPlot::mousePressEvent(event);
}

void HQCustomPlot::mouseReleaseEvent(QMouseEvent *event)
{
    if(this->activeMarkerIdx >= 0)
    {
        mMarkers[activeMarkerIdx]->setSelected(false);
    }
    this->markerText->setSelected(false);
    this->replot();
    QCustomPlot::mouseReleaseEvent(event);
}

void HQCustomPlot::mouseMoveEvent(QMouseEvent *event)
{
    if(this->markerText->selected())
    {
        this->markerText->position->setPixelPoint(QPointF(event->x(), event->y()));
        this->replot();
    }
    else if(this->activeMarkerIdx >= 0)
    {
        this->mMarkers[activeMarkerIdx]->setGraphKey(this->xAxis->pixelToCoord(event->x()));
        this->replot();
    }
    QCustomPlot::mouseMoveEvent(event);
}

void HQCustomPlot::SetMarkerTextEn(bool enable)
{
    this->mMarkerTextEn = enable;
}

void HQCustomPlot::updateMarkerText(bool enable)
{
    this->markerText->setVisible(enable);
    if(!enable)
        return;

    int n;
    double deltaKey=0.0;
    double deltaVal=0.0;
    QString message = "Marker Value:\n";
    for(n=0;n<MARKERNUM;n++)
    {
        if(this->mMarkers[n]->visible())
        {
            if(mMarkers[n]->GetDeltaEn())
            {
                deltaKey = mMarkers[n]->graphKey() - mMarkers[mMarkers[n]->GetDeltarRef()]->graphKey();
                deltaVal = mMarkers[n]->position->value() - mMarkers[mMarkers[n]->GetDeltarRef()]->position->value();
                message += QString("D%1(%4)  %2  %3\n").arg(this->mMarkers[n]->GetText()).arg(deltaKey, 0, 'G', 4, QLatin1Char('0')).arg( deltaVal, 0, 'G', 4, QLatin1Char('0')).arg(this->mMarkers[n]->GetDeltarRef()+1);
            }
            else
            {
                message += QString("M%1      %2  %3\n").arg(this->mMarkers[n]->GetText()).arg(this->mMarkers[n]->graphKey(), 0, 'G', 4, QLatin1Char('0')).arg( this->mMarkers[n]->position->value(), 0, 'G', 4, QLatin1Char('0'));
            }
        }
    }
    this->markerText->setText(message);
}

void HQCustomPlot::replot()
{
    this->updateMarkerText(this->mMarkerTextEn);
    QCustomPlot::replot();
}
